package gbench.appdemo.myworld.junit.eco;

import gbench.appdemo.myworld.economy.Economy;
import gbench.appdemo.myworld.util.Latch;
import static gbench.common.tree.LittleTree.IRecord.*;
import static gbench.common.tree.LittleTree.*;

import java.io.*;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;

/**
 * 这是一个 简单的经济体的用法的 演示示例。
 * @author gbench
 *
 */
public class JunitE1 {
    
    @Test
    public void foo() {
        final var latch = new Latch(2);// 生产活动控制锁
        final var program_latch = new Latch(1);
        final var ai = new AtomicInteger(0);
        final var MAX_COUNT = 10000;
        new Economy(1024) // 构造一个经济体
        .produce(ecom->{
            while(true) {
                ecom.publish(REC("producer",1,"id",ai.getAndIncrement()));
                if(ai.get()>MAX_COUNT) {
                    latch.countdown();
                    break;
                }
            }// while
        }).produce(ecom->{
            while(true) {
                ecom.publish(REC("producer",2,"id",ai.getAndIncrement()));
                if(ai.get()>MAX_COUNT) {
                    latch.countdown();
                    break;
                }
            }// while
        }).consume(event -> {// 社会生活
            System.out.println("1)"+event);
        }).consume(event -> {// 社会生活
            System.out.println("2)"+event);
        }).consume(event -> {// 社会生活
            System.out.println("3)"+event);
        }).collect(e -> {
            latch.await();// 等待producer 运行结束
            Stream.of(5000l).forEach(trycatch3(Thread::sleep));
            
            // 书写日志文件
            Stream.of("JunitE1 运行完毕").forEach(line->{ // 书写一行数据
                final var constructor = compose_ef(BufferedWriter::new,(ExceptionalFunction<String,FileWriter>)FileWriter::new);// 构造函数
                final var bw = Optional.of("d:/sliced/tmp/a.txt").map(trycatch(constructor)).get();// 创建书写器
                Stream.of(bw).forEach(trycatch2(writer->writer.append(line)));// 书写内容
                Stream.of(bw).forEach(trycatch3(Writer::close)); // 关闭书写器
            });
            
            e.shutdown();
            System.out.println("shutdown");
            program_latch.countdown();
        });
        
        program_latch.await();
        System.out.println("程序运行结束");
    }

}
